package com.lightsaber.trade.as.web.category;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springside.modules.orm.Page;
import org.springside.modules.utils.web.struts2.Struts2Utils;

import com.lightsaber.trade.as.entity.category.CategoryLeaf;
import com.lightsaber.trade.as.entity.category.CategoryNode;
import com.lightsaber.trade.as.entity.category.CategoryProgrammeAttribute;
import com.lightsaber.trade.as.entity.programme.Programme;
import com.lightsaber.trade.as.service.category.CategoryNodeService;
import com.lightsaber.trade.as.service.category.CategoryProgrammeAttributeService;
import com.lightsaber.trade.as.service.param.ParamObject;
import com.lightsaber.trade.as.service.param.ParamService;
import com.lightsaber.trade.as.service.programme.ProgrammeManager;
import com.lightsaber.trade.core.entity.BaseEntity;
import com.lightsaber.trade.core.web.BaseAction;

@Namespace("/category")
@Action(value = "categoryProgrammeAttribute")
@Results({
        @Result(name = "create-edit-programme-attributes", location = "create-edit-programme-attributes.jsp"),
        @Result(name = "category-edit-leaf-attribute", location = "category-edit-leaf-attribute.jsp"),
        @Result(name = "preview-programme-attributes", location = "preview-programme-attributes.jsp") })
public class CategoryProgrammeAttributeAction extends BaseAction {

    private static final long serialVersionUID = -6133932528005700711L;

    private static final Logger log = LoggerFactory
            .getLogger(CategoryProgrammeAttributeAction.class);

    @Autowired
    private transient CategoryProgrammeAttributeService attService;
    @Autowired
    private ParamService paramService;
    @Autowired
    private transient CategoryNodeService categoryNodeService;

    @Autowired
    private transient ProgrammeManager programmeManager;

    private List<CategoryProgrammeAttribute> attList;
    private List<String> attListSelected;

    private CategoryProgrammeAttribute attribute;
    private String categoryNodeId;
    private String categoryNodeType;
    private String treeType;
    private String attrValue;
    private String attrCode;

    private String categoryId;

    private String categoryNodeName;

    private Page<Programme> page;
    @Value(value = "#{appProperties['programme.page.size']}")
    private String pageSize;

    private String fundingMode;

    /**
     * list root roles
     */

    @Override
    public String execute() {
        return list();
    }

    public String list() {
        attList = attService.findByCategoryNodeId(categoryNodeId);

        CategoryLeaf node = (CategoryLeaf) categoryNodeService.findById(categoryNodeId);

        String fm = node.getFundingMode();
        String label = paramService.getFundingModeLabel(fm);
        setFundingMode(label);
        setAttList(attList);
        setCategoryNodeId(categoryNodeId);
        setCategoryNodeType(categoryNodeType);
        setTreeType(treeType);
        setCategoryId(categoryId);
        return "create-edit-programme-attributes";
    }

    /**
     * load add leaf attribute page
     */

    public String loadAddAttributePage() {
        if (attribute != null && StringUtils.isNotBlank(attribute.getId())) {
            attribute = attService.findById(attribute.getId());
            setAttribute(attribute);
        }
        return "category-edit-leaf-attribute";
    }

    /**
     * get different drop down list by different attribute
     */
    public void getAttrValues() {
        List<ParamObject> listAttCodeMapValue = getByCode(attribute.getProgrammeAttribute());
        Struts2Utils.renderJson(listAttCodeMapValue);
    }

    public List<ParamObject> getByCode(final String code) {
        return paramService.getByCode(code);

    }

    /**
     * save root roles;
     */
    public String save() throws Exception {
        // get leaf
        if (StringUtils.isBlank(attribute.getId())) {
            CategoryLeaf categoryLeaf = categoryNodeService.findLeafById(categoryNodeId);
            attribute.setCategoryLeaf(categoryLeaf);
        }
        log.info(" attr : {}", attribute.getProgrammeAttribute());
        log.info(" value : {}", attribute.getValue());
        attService.save(attribute);

        addActionMessage(getText(PROCESSED_SUCCESS));

        return list();
    }

    public String getResultSet() {
        if (page == null) {
            page = new Page<Programme>(Integer.valueOf(pageSize));
        } else {
            page.setPageSize(Integer.valueOf(pageSize));
        }

        if (!page.isOrderBySetted()) {
            page.setOrderBy(BaseEntity.ID);
            page.setOrder(Page.ASC);
        }
        CategoryLeaf leaf = categoryNodeService.findLeafById(categoryNodeId);
        setCategoryNodeName(leaf.getName());

        programmeManager.viewResultSet(categoryId, leaf, page);

        setCategoryNodeId(categoryNodeId);
        setCategoryId(categoryId);
        setCategoryNodeType(categoryNodeType);
        return "preview-programme-attributes";
    }

    @Override
    public String input() throws Exception {
        return INPUT;
    }

    public String delete() throws Exception {
        attService.deleteMultitude(attListSelected);

        addActionMessage(getText(PROCESSED_SUCCESS));

        return list();
    }

    public void getAttributeLabel() {

        Map<String, String> map = new HashMap<String, String>();
        String code = "";
        if (attrCode.equals(paramService.FUNDING_MODE)) {
            code = "Funding Mode";
        } else {
            code = paramService.getTypeLabel(attrCode);
        }
        String value = paramService.getLableByCodeAndValue(attrCode, attrValue);

        map.put("code", code);
        map.put("value", value);
        Struts2Utils.renderJson(map);
    }

    public List<CategoryProgrammeAttribute> getAttList() {
        return attList;
    }

    public void setAttList(final List<CategoryProgrammeAttribute> attList) {
        this.attList = attList;
    }

    public String getAttrValue() {
        return attrValue;
    }

    public void setAttrValue(final String attrValue) {
        this.attrValue = attrValue;
    }

    public String getCategoryNodeId() {
        return categoryNodeId;
    }

    public void setCategoryNodeId(final String categoryNodeId) {
        this.categoryNodeId = categoryNodeId;
    }

    public ParamService getParamService() {
        return paramService;
    }

    public void setParamService(final ParamService paramService) {
        this.paramService = paramService;
    }

    public String getAttrCode() {
        return attrCode;
    }

    public void setAttrCode(final String attrCode) {
        this.attrCode = attrCode;
    }

    public String getCategoryNodeType() {
        return categoryNodeType;
    }

    public void setCategoryNodeType(final String categoryNodeType) {
        this.categoryNodeType = categoryNodeType;
    }

    public CategoryProgrammeAttribute getAttribute() {
        return attribute;
    }

    public void setAttribute(final CategoryProgrammeAttribute attribute) {
        this.attribute = attribute;
    }

    public List<String> getAttListSelected() {
        return attListSelected;
    }

    public void setAttListSelected(final List<String> attListSelected) {
        this.attListSelected = attListSelected;
    }

    public ProgrammeManager getProgrammeManager() {
        return programmeManager;
    }

    public void setProgrammeManager(final ProgrammeManager programmeManager) {
        this.programmeManager = programmeManager;
    }

    public Page<Programme> getPage() {
        return page;
    }

    public void setPage(final Page<Programme> page) {
        this.page = page;
    }

    public String getTreeType() {
        return treeType;
    }

    public void setTreeType(final String treeType) {
        this.treeType = treeType;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(final String categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryNodeName() {
        return categoryNodeName;
    }

    public void setCategoryNodeName(final String categoryNodeName) {
        this.categoryNodeName = categoryNodeName;
    }

    public String getFundingMode() {
        return fundingMode;
    }

    public void setFundingMode(final String fundingMode) {
        this.fundingMode = fundingMode;
    }

    public String getPageSize() {
        return pageSize;
    }

    public void setPageSize(final String pageSize) {
        this.pageSize = pageSize;
    }
}
